package com.tgu.home_action.service.annotation;


import com.alibaba.fastjson.JSON;
import com.tgu.home_action.dao.LogMapper;
import com.tgu.home_action.pojo.*;
import com.tgu.home_action.pojo.annotation.MyLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


/**
 * 系统日志：切面处理类
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    private Logger logger;
    @Autowired
    private LogMapper logMapper;

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation( com.tgu.home_action.pojo.annotation.MyLog)")
    public void logPointCut() {
    }

    //切面 配置通知
    @AfterReturning(pointcut = "logPointCut()", returning = "returning")
    public void saveSysLog(JoinPoint joinPoint, Object returning) {
        try {
            //从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //获取切入点所在的方法
            Method method = signature.getMethod();
            //获取注解
            MyLog myLog = method.getAnnotation(MyLog.class);
            String role = myLog.role();
            int actionType = myLog.type();
            int actionId = myLog.actionId();
            String comment = myLog.comment();

            //获取request
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            //从获取RequestAttributes中获取HttpServletRequest的信息
            assert requestAttributes != null;
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

            //获取ip
            assert request != null;
            String ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if (ip.contains(",")) {
                ip = ip.split(",")[0];
            }

            //获取返回结果
            ResponseData<Object> responseData = (ResponseData<Object>) returning;
            String result = responseData.getMessage();

            //获取userId
            int userId = 0;
            switch (role) {
                case "family":
                    Family family = (Family) request.getAttribute("family");
                    if (family == null) {
                        family = (Family) responseData.getData();
                    }
                    if (family != null) {
                        userId = family.getId();
                    }
                    break;
                case "volunteer":
                    Volunteer volunteer = (Volunteer) request.getAttribute("volunteer");
                    if (volunteer == null) {
                        volunteer = (Volunteer) responseData.getData();
                    }
                    if (volunteer != null) {
                        userId = volunteer.getId();
                    }
                    break;
                case "admin":
                    Admin admin = (Admin) request.getAttribute("admin");
                    if (admin == null) {
                        admin = (Admin) responseData.getData();
                    }
                    if (admin != null) {
                        userId = admin.getId();
                    }
                    break;
            }
            if (userId != 0) {
                Log log = new Log(userId, role, actionId, actionType, result, comment, ip);
                logMapper.insertLog(log);
            }
        } catch (Exception e) {
            logger.error("日志保存失败");
            logger.error(e.getMessage());
        }
    }

}
